package com.xunsiya.common.config.util;

import com.sun.imageio.plugins.jpeg.JPEGImageWriter;
import com.xunsiya.tools.common.config.PathUtils;
import com.xunsiya.tools.file.type.FileTypeJudge;
import org.apache.log4j.Logger;
import org.springframework.util.ObjectUtils;
import org.w3c.dom.Element;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 图片工具类
 *
 * @author panjun
 * @version 1.0
 *          <p>
 *          <p>修订人		修订时间			描述信息
 *          <p>-----------------------------------------------------
 *          <p>panjun		2018/12/3		初始创建
 */
public class ImgUtil {

    private static Logger log = Logger.getLogger(ImgUtil.class);

    /**
     * 图片压缩
     *
     * @param f    图片所在的文件夹路径
     * @param file 图片路径
     * @param ext  扩展名
     * @param n    图片名
     * @param w    目标宽
     * @param h    目标高
     * @param per  百分比
     */
    private static void toSmallerPic(String f, File file, String ext, String n, int w, int h, float per) {
        Image src;
        try {
            // 构造Image对象
            src = ImageIO.read(file);

            String imgMidName = f + n.substring(0, n.indexOf(".")) + ext + n.substring(n.indexOf("."));
            // 得到源图宽
            int oldW = src.getWidth(null); 
            int oldH = src.getHeight(null);
            int newW;
            // 得到源图长
            int newH; 

            double w2 = (oldW * 1.00) / (w * 1.00);
            double h2 = (oldH * 1.00) / (h * 1.00);

            //图片跟据长宽留白，成一个正方形图。
            BufferedImage oldPic;
            if (oldW > oldH) {
                oldPic = new BufferedImage(oldW, oldW, BufferedImage.TYPE_INT_RGB);
            } else {
                if (oldW < oldH) {
                    oldPic = new BufferedImage(oldH, oldH, BufferedImage.TYPE_INT_RGB);
                } else {
                    oldPic = new BufferedImage(oldW, oldH, BufferedImage.TYPE_INT_RGB);
                }
            }
            Graphics2D g = oldPic.createGraphics();
            g.setColor(Color.white);
            if (oldW > oldH) {
                g.fillRect(0, 0, oldW, oldW);
                g.drawImage(src, 0, (oldW - oldH) / 2, oldW, oldH, Color.white, null);
            } else {
                if (oldW < oldH) {
                    g.fillRect(0, 0, oldH, oldH);
                    g.drawImage(src, (oldH - oldW) / 2, 0, oldW, oldH, Color.white, null);
                } else {
                    g.drawImage(src.getScaledInstance(oldW, oldH, Image.SCALE_SMOOTH), 0, 0, null);
                }
            }
            g.dispose();
            src = oldPic;
            // 图片调整为方形结束
            if (oldW > w) {
                newW = (int) Math.round(oldW / w2);
            } else {
                newW = oldW;
            }
            if (oldH > h) {
                // 计算新图长宽
                newH = (int) Math.round(oldH / h2);
            } else {
                newH = oldH;
            }
            BufferedImage imageToSave = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_RGB);
            imageToSave.getGraphics().drawImage(src.getScaledInstance(newW, newH, Image.SCALE_SMOOTH), 0, 0, null);
            // 输出到文件流
            FileOutputStream fos = new FileOutputStream(imgMidName); 

            // 新的方法
            saveAsJPEG(100, imageToSave, per, fos);

            fos.close();
        } catch (IOException ex) {
            //Logger.getLogger(Img_Middle.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 以JPEG编码保存图片
     *
     * @param dpi             分辨率
     * @param imageToSave   要处理的图像图片
     * @param compression 压缩比
     * @param fos             文件输出流
     * @throws IOException
     */
    public static void saveAsJPEG(Integer dpi, BufferedImage imageToSave, float compression, FileOutputStream fos) throws IOException {

        // Image writer
        JPEGImageWriter imageWriter = (JPEGImageWriter) ImageIO.getImageWritersBySuffix("jpg").next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
        imageWriter.setOutput(ios);
        //and metadata
        IIOMetadata imageMetaData = imageWriter.getDefaultImageMetadata(new ImageTypeSpecifier(imageToSave), null);


        if (!ObjectUtils.isEmpty(dpi)) {

            //new metadata
            Element tree = (Element) imageMetaData.getAsTree("javax_imageio_jpeg_image_1.0");
            Element jfif = (Element) tree.getElementsByTagName("app0JFIF").item(0);
            jfif.setAttribute("Xdensity", Integer.toString(dpi));
            jfif.setAttribute("Ydensity", Integer.toString(dpi));

        }

        if (compression >= 0 && compression <= 1.0) {

            // new Compression
            JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
            jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
            jpegParams.setCompressionQuality(compression);

        }

        //new Write and clean up
        imageWriter.write(imageMetaData, new IIOImage(imageToSave, null, null), null);
        ios.close();
        imageWriter.dispose();

    }

    /**
     * 图片按高度比例自动缩放
     *
     * @param path         图片地址
     * @param maxWidth     允许缩放最大宽度
     * @param maxHeight    允许缩放最大高度
     */
    public static String zoomImage(String path, int maxWidth, int maxHeight) {
        try {
            // 读取图片信息
            if (path.indexOf(PathUtils.getBaseUrl()) > -1) {
                path = path.replace(PathUtils.getBaseUrl(), PathUtils.getBasePath());
            }

            if (!FileTypeJudge.isImage(path)) {
                return "";
            }

            File imageFile = new File(path);
            BufferedImage sourceImg = ImageIO.read(new FileInputStream(imageFile));

            // 用于设定图片的宽度和高度
            int tempWidth;
            int tempHeight;

            int width = sourceImg.getWidth();
            int height = sourceImg.getHeight();
            if (width > 0 && height > 0) {
                // 原图片的宽高比例 大于 指定的宽高比例，说明原图片的宽度大于最大宽度
                if (width / height >= maxWidth / maxHeight) {
                    if (width > maxWidth) {
                        tempWidth = maxWidth;
                        // 按原图的比例进行缩放
                        tempHeight = (height * maxWidth) / width;
                    } else {
                        // 按原图的大小进行缩放
                        tempWidth = width;
                        tempHeight = height;
                    }
                } else {
                    if (height > maxHeight) {
                        tempHeight = maxHeight;
                        // 按原图的比例进行缩放
                        tempWidth = (width * maxHeight) / height;
                    } else {
                        // 按原图的大小进行缩放
                        tempWidth = width;
                        tempHeight = height;
                    }
                }
                return "width:" + tempWidth + "px; height:" + tempHeight + "px;";
            }
        } catch (Exception e) {
            log.info(path + "图片读取失败");
        }
        return "";
    }
}
